#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_ocs; //对象坐标空间中的顶点位置
layout(location = 1) in vec2 vertexUV; //顶点的纹理坐标


// Output data ; will be interpolated for each fragment.
out vec2 UV;
//>>>>TASK1
uniform sampler2D heightmapTexture;//代表高度图的2D纹理

//>>>>TASK2
out vec3 Normal;//传递法线到片元着色器

//>>>>TASK3
uniform mat4 ViewMatrix;//传入视图矩阵
uniform mat4 ModelMatrix;//传入模型矩阵
uniform vec3 LightPos;//传入光源位置

out vec3 LightDir_vcs;//视图坐标系下光的方向
out vec3 ViewDir_vcs;//视图坐标系下的相机方向
out vec3 NormalDir_vcs;//视图坐标系下的法线方向
out vec3 VertPos_vcs;// 传递视图坐标中的顶点位置到片段着色器,fragViewPosition

//>>>>TASK4
out vec3 TangentDir_vcs;//表示切线方向在视图坐标系（View Coordinate System）中的方向
out vec3 BitangentDir_vcs;//表示副切线方向在视图坐标系中的方向
out mat3 TBN;

//>>>>TASK5
out float heightValue;//传出高度

//>>>>TASK6
uniform float terrainScale;

// Values that stay constant for the whole mesh.
uniform mat4 MVP; //模型-视图-投影矩阵


void main(){

	// Output position of the vertex, in clip space : MVP * position
	gl_Position =  MVP * vec4(vertexPosition_ocs,1);	

	// UV of the vertex. No special space for this one.
	UV = vertexUV;

	//>>>>>TASK1: height

	// Sample heightmap texture and adjust vertex position
	// Sample the heightmap texture at the current UV coordinates
	//存储纹理颜色
	vec3 heightColor = texture(heightmapTexture, UV) .rgb;
	//计算RGB对应的高度
	float heightscale = 2300;
    heightValue = (heightColor.r * 256 * 256 + heightColor.g * 256 + heightColor.b)/heightscale;
	heightValue = heightValue * terrainScale;
    vec3 vertexPosition = vertexPosition_ocs + vec3(0, heightValue, 0);
		
	// Output position of the vertex, in clip space : MVP * position
	gl_Position =  MVP * vec4(vertexPosition,1.0);

	// Calculate the normal using height differences
	//1/200
    float delta = 0.005; // Adjust this based on your scene dimensions

	//采样邻近像素的纹理
	//heightmapTexture 是一个2D纹理,UV 是顶点的纹理坐标
	//UV + vec2(-1.0/sceneLength, 1.0/sceneLength) 表示在纹理坐标 UV 的基础上，加上一个偏移量
	//这个偏移量是通过 vec2(-1.0/sceneLength, 1.0/sceneLength) 计算得到的
	vec3 heightColor_0 = texture(heightmapTexture, UV + vec2(-delta, delta)).rgb;
	vec3 heightColor_1 = texture(heightmapTexture, UV + vec2(0,delta)).rgb;
	vec3 heightColor_2 = texture(heightmapTexture, UV + vec2(delta,delta)).rgb;
	vec3 heightColor_3 = texture(heightmapTexture, UV + vec2(-delta,0)).rgb;

	vec3 heightColor_5 = texture(heightmapTexture, UV + vec2(delta,0)).rgb;
	vec3 heightColor_6 = texture(heightmapTexture, UV + vec2(-delta,-delta)).rgb;
	vec3 heightColor_7 = texture(heightmapTexture, UV + vec2(0,-delta)).rgb;
	vec3 heightColor_8 = texture(heightmapTexture, UV + vec2(delta,-delta)).rgb;

	// Calculate height(rgb to heightvalue)
	float heightscale2 = 20;
	float height_0 = (heightColor_0.r*256*256 + heightColor_0.g*256 + heightColor_0.b)/heightscale2;
	float height_1 = (heightColor_1.r*256*256 + heightColor_1.g*256 + heightColor_1.b)/heightscale2;
	float height_2 = (heightColor_2.r*256*256 + heightColor_2.g*256 + heightColor_2.b)/heightscale2;
	float height_3 = (heightColor_3.r*256*256 + heightColor_3.g*256 + heightColor_3.b)/heightscale2;

	float height_5 = (heightColor_5.r*256*256 + heightColor_5.g*256 + heightColor_5.b)/heightscale2;
	float height_6 = (heightColor_6.r*256*256 + heightColor_6.g*256 + heightColor_6.b)/heightscale2;
	float height_7 = (heightColor_7.r*256*256 + heightColor_7.g*256 + heightColor_7.b)/heightscale2;
	float height_8 = (heightColor_8.r*256*256 + heightColor_8.g*256 + heightColor_8.b)/heightscale2;

    float Nx = abs(0.1 * (height_0 - height_6) + 0.5 * (height_1 - height_7) + 0.1 * (height_2 - height_8));
	float Ny = 1; // 固定值 // 0.01;
	float Nz = abs(0.1 * (height_0 - height_2) + 0.5 * (height_3 - height_5) + 0.1 * (height_6 - height_8));
	// 归一化法向量
	Normal = normalize(vec3(Nx, Ny, Nz));	


	//>>>>TASK3:ROCK

	//计算当前顶点在视图坐标系的位置
	//VertPos_vcs = vec3(MVP * vec4(vertexPosition,1.0));
	VertPos_vcs = vec3(ViewMatrix * ModelMatrix * vec4(vertexPosition,1.0));

	//计算法线方向
	NormalDir_vcs = vec3(ViewMatrix * ModelMatrix * vec4(Normal,0.0));
	//NormalDir_vcs = Normal;

	//计算光照方向
	//将光的位置转化为vcs
	vec3 LightPos_vcs = vec3(ViewMatrix *vec4(LightPos,0.0));
	//光的方向 = 光位置 - 顶点位置
	LightDir_vcs = normalize(- LightPos_vcs );

	//计算视线方向
	//计算相机位置
	vec3 viewPos_vcs = vec3(ViewMatrix[3]);
	ViewDir_vcs = normalize(vec3(0,0,0) - VertPos_vcs);

	//>>>>TASK4:法线贴图

	// 由于使用的是高度图, 所以tangent是(1,0,0),bitangent是(0,0,1),Normal是Task2里计算的结果
	vec3 normal_TBN = NormalDir_vcs; 
	vec3 tangent_TBN =  vec3(1,0,0); 
	vec3 bitangent_TBN = vec3(0,0,1); 
	// 使用Gram-Schmidt orthogonalization方法来使TBN矩阵正交
	normal_TBN = normal_TBN;
	tangent_TBN = normalize(tangent_TBN - dot(normal_TBN,tangent_TBN));//tangent_TBN * 
	bitangent_TBN = normalize(cross(tangent_TBN,normal_TBN));
	// 构建修正后的 TBN 矩阵
	TBN = mat3(tangent_TBN,bitangent_TBN,normal_TBN);


	
}
